Skip to content

[C] Do not diagnose flexible array members with -Wdefault-const-init-field-unsafe #140578

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 20, 2025

Conversation

AaronBallman
Copy link
Collaborator

This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following:

  struct S {
    int len;
    const char fam[];
  } s;

despite it being invalid to initialize the flexible array member.

Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized.

…field-unsafe

This addresses post-commit review feedback from someone who discovered
that we diagnosed code like the following:

  struct S {
    int len;
    const char fam[];
  } s;

despite it being invalid to initialize the flexible array member.

Note, this applies to flexible array members and zero-sized arrays at
the end of a structure (an old-style flexible array member), but it
does not apply to one-sized arrays at the end of a structure because
those do occupy storage that can be initialized.
@AaronBallman AaronBallman added clang Clang issues not falling into any other category c clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 19, 2025
@llvmbot
Copy link
Member

llvmbot commented May 19, 2025

@llvm/pr-subscribers-clang

Author: Aaron Ballman (AaronBallman)

Changes

This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following:

  struct S {
    int len;
    const char fam[];
  } s;

despite it being invalid to initialize the flexible array member.

Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized.


Full diff: https://github.com/llvm/llvm-project/pull/140578.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaInit.cpp (+8)
  • (modified) clang/test/Sema/warn-default-const-init.c (+30)
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 9ee8603ff7811..e17e68966dc00 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6513,6 +6513,14 @@ static bool canPerformArrayCopy(const InitializedEntity &Entity) {
 static const FieldDecl *getConstField(const RecordDecl *RD) {
   assert(!isa<CXXRecordDecl>(RD) && "Only expect to call this in C mode");
   for (const FieldDecl *FD : RD->fields()) {
+    // If the field is a flexible array member, we don't want to consider it
+    // as a const field because there's no way to initialize the FAM anyway.
+    if (Decl::isFlexibleArrayMemberLike(
+            FD->getASTContext(), FD, FD->getType(),
+            LangOptions::StrictFlexArraysLevelKind::ZeroOrIncomplete,
+            /*IgnoreTemplateOrMacroSubstitution=*/true))
+      continue;
+
     QualType QT = FD->getType();
     if (QT.isConstQualified())
       return FD;
diff --git a/clang/test/Sema/warn-default-const-init.c b/clang/test/Sema/warn-default-const-init.c
index e788d72899685..e6ff0aa783e23 100644
--- a/clang/test/Sema/warn-default-const-init.c
+++ b/clang/test/Sema/warn-default-const-init.c
@@ -85,3 +85,33 @@ void func() {
   static const int b; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
                          cxx-error {{default initialization of an object of const type 'const int'}}
 }
+
+// Test the behavior of flexible array members. Those cannot be initialized
+// when a stack-allocated object of the structure type is created. We handle
+// degenerate flexible arrays similarly, but only if the array does not
+// actually specify any storage. Note that C++ does not have flexible array
+// members at all, which is why the test is disabled there.
+#ifndef __cplusplus
+struct RealFAM {
+  int len;
+  const char fam[];
+};
+
+struct FakeFAM {
+  int len;
+  const char fam[0];
+};
+
+struct NotTreatedAsAFAM {
+  int len;
+  const char fam[1];              // unsafe-field-note {{member 'fam' declared 'const' here}} \
+                                     unsafe-field-compat-note {{member 'fam' declared 'const' here}}
+};
+
+void test_fams() {
+  struct RealFAM One;
+  struct FakeFAM Two;
+  struct NotTreatedAsAFAM Three;  // unsafe-field-warning {{default initialization of an object of type 'struct NotTreatedAsAFAM' with const member leaves the object uninitialized}} \
+                                     unsafe-field-compat-warning {{default initialization of an object of type 'struct NotTreatedAsAFAM' with const member leaves the object uninitialized and is incompatible with C++}}
+}
+#endif // !defined(__cplusplus)

@AaronBallman AaronBallman merged commit c555c8d into llvm:main May 20, 2025
9 of 10 checks passed
@AaronBallman AaronBallman deleted the aballman-def-const-init-fam branch May 20, 2025 18:40
kostasalv pushed a commit to kostasalv/llvm-project that referenced this pull request May 21, 2025
…field-unsafe (llvm#140578)

This addresses post-commit review feedback from someone who discovered
that we diagnosed code like the following:
```
  struct S {
    int len;
    const char fam[];
  } s;
```
despite it being invalid to initialize the flexible array member.

Note, this applies to flexible array members and zero-sized arrays at
the end of a structure (an old-style flexible array member), but it does
not apply to one-sized arrays at the end of a structure because those do
occupy storage that can be initialized.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants